package com.sooth.micro.camunda.converter.processing.event;

import com.sooth.common.json.utils.JsonUtils;
import com.sooth.micro.camunda.converter.bean.BaseDefinition;
import com.sooth.micro.camunda.converter.bean.BpmnElementType;
import com.sooth.micro.camunda.converter.bean.event.start.*;
import com.sooth.micro.camunda.converter.bean.extension.ExtBpmConstant;
import com.sooth.micro.camunda.converter.processing.BpmnElementProcessor;
import com.sooth.micro.camunda.converter.processing.BpmnElementProcessors;
import org.apache.commons.lang3.StringUtils;
import org.camunda.bpm.model.bpmn.builder.StartEventBuilder;
import org.camunda.bpm.model.bpmn.instance.ExtensionElements;
import org.camunda.bpm.model.bpmn.instance.StartEvent;
import org.camunda.bpm.model.bpmn.instance.camunda.CamundaProperty;

import java.lang.reflect.InvocationTargetException;
import java.util.Objects;

public class StartEventProcessor
        implements BpmnElementProcessor<StartEventDefinition, StartEventBuilder> {

    @Override
    public String onComplete(StartEventBuilder startEventBuilder, StartEventDefinition flowNode)
            throws InvocationTargetException, IllegalAccessException {
        // 事件类型 timer/message 默认：none
        String eventType = flowNode.getEventType();
        String nodeName = flowNode.getNodeName();
        startEventBuilder.id(flowNode.getId());
        startEventBuilder.name(nodeName);
        startEventBuilder.camundaFormKey(String.valueOf(flowNode.getPageId()));
        StartEvent startEvent = startEventBuilder.getElement();
        ExtensionElements extensionElements = startEvent.getModelInstance().newInstance(ExtensionElements.class);
        CamundaProperty camundaProperty = extensionElements.addExtensionElement(CamundaProperty.class);
        camundaProperty.setAttributeValue(ExtBpmConstant.FORM_PERM, JsonUtils.toJsonString(flowNode.getFormPermList()));
        camundaProperty.setAttributeValue(ExtBpmConstant.BUTTON_PERM, JsonUtils.toJsonString(flowNode.getButtonPermList()));
        startEvent.setExtensionElements(extensionElements);
        if (StringUtils.isNotBlank(eventType)) {
            if (EventType.TIMER.isEqual(eventType)) {
                TimerStartEventDefinition timer = (TimerStartEventDefinition) flowNode;
                // timer 定义类型： date/cycle/duration
                String timerDefinitionType = timer.getTimerDefinitionType();
                if (TimerDefinitionType.DATE.isEqual(timerDefinitionType)) {
                    String timerDefinition = timer.getTimerDefinition();
                    startEventBuilder.timerWithDate(timerDefinition);
                } else if (TimerDefinitionType.DURATION.isEqual(timerDefinitionType)) {
                    String timerDefinition = timer.getTimerDefinition();
                    startEventBuilder.timerWithDuration(timerDefinition);
                } else if (TimerDefinitionType.CYCLE.isEqual(timerDefinitionType)) {
                    String timerDefinition = timer.getTimerDefinition();
                    startEventBuilder.timerWithCycle(timerDefinition);
                }
            } else if (EventType.MESSAGE.isEqual(eventType)) {
                MessageStartEventDefinition message = (MessageStartEventDefinition) flowNode;
                String messageName = message.getMessageName();
                startEventBuilder.message(messageName);
            }
        }

        // create execution listener
        createExecutionListener(startEventBuilder, flowNode);

        String id = startEventBuilder.getElement().getId();
        BaseDefinition nextNode = flowNode.getNextNode();
        if (Objects.isNull(nextNode)) {
            return id;
        }

        BpmnElementType elementType = BpmnElementType.bpmnElementTypeFor(nextNode.getNodeType());
        return BpmnElementProcessors.getProcessor(elementType)
                .onComplete(moveToNode(startEventBuilder, id), nextNode);
    }
}
